home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * "Irit" - the 3d (not only polygonal) solid modeller. *
- * *
- * Written by: Gershon Elber Ver 0.2, Mar. 1990 *
- ******************************************************************************
- * Module to provide the required interfact for the cagd library for the *
- * free form surfaces and curves. *
- *****************************************************************************/
-
- #include <stdio.h>
- #include <math.h>
- #include "program.h"
- #include "allocate.h"
- #include "attribut.h"
- #include "objects.h"
- #include "primitiv.h"
- #include "windows.h"
- #include "ip_cnvrt.h"
- #include "freeform.h"
-
- #define MIN_FREE_FORM_RES 2
-
- static IPObjectStruct *ComputeCurveIsoLines(IPObjectStruct *PObj,
- int Optimal);
- static IPObjectStruct *ComputeSurfaceIsoLines(IPObjectStruct *PObj,
- int Optimal);
- static IPObjectStruct *ComputeTrimSrfIsoLines(IPObjectStruct *PObj,
- int Optimal);
- static IPObjectStruct *ComputeTrivarIsoLines(IPObjectStruct *PObj,
- int Optimal);
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to reverse a curve. M
- * *
- * PARAMETERS: M
- * CrvObj: Curve to reverse its parametrization. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: Reversed curve. M
- * *
- * KEYWORDS: M
- * CurveReverse M
- *****************************************************************************/
- IPObjectStruct *CurveReverse(IPObjectStruct *CrvObj)
- {
- CagdCrvStruct
- *RevCrv = CagdCrvReverse(CrvObj -> U.Crvs);
-
- if (RevCrv == NULL)
- return NULL;
-
- CrvObj = GenCRVObject(RevCrv);
-
- return CrvObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to reverse a surface. M
- * *
- * PARAMETERS: M
- * SrfObj: Surface to reverse. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: Reversed surface. The normal of the reversed M
- * surface is flipped with respected to the original M
- * surface, SrfObj, by 180 degrees. M
- * *
- * KEYWORDS: M
- * SurfaceReverse M
- *****************************************************************************/
- IPObjectStruct *SurfaceReverse(IPObjectStruct *SrfObj)
- {
- CagdSrfStruct
- *RevSrf = CagdSrfReverse(SrfObj -> U.Srfs);
-
- if (RevSrf == NULL)
- return NULL;
-
- SrfObj = GenSRFObject(RevSrf);
-
- return SrfObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Routine to convert curve(s) to a piecewise linear polyline approximation *
- * and convert its control polygon into polyline as well. *
- * *
- * PARAMETERS: *
- * PObj: Curves to approximate using piecewise linear approximation. *
- * Optimal: Do we want an optimal sampling but expensive approach? *
- * *
- * RETURN VALUE: *
- * IPObjectStruct *: A polyline approximation to PObj. *
- *****************************************************************************/
- static IPObjectStruct *ComputeCurveIsoLines(IPObjectStruct *PObj, int Optimal)
- {
- int Resolution = GetResolution(FALSE);
- IPObjectStruct *PObjPoly;
- CagdCrvStruct *Crv;
-
- if (!IP_IS_CRV_OBJ(PObj))
- IritFatalError("Curve was expected.");
-
- if (Resolution < MIN_FREE_FORM_RES)
- Resolution = MIN_FREE_FORM_RES;
-
- PObjPoly = GenPOLYObject(NULL);
- PObjPoly -> Attrs = AttrCopyAttributes(PObj -> Attrs);
- IP_SET_POLYLINE_OBJ(PObjPoly);
- for (Crv = PObj -> U.Crvs; Crv != NULL; Crv = Crv -> Pnext) {
- IPPolygonStruct *Poly;
-
- Poly = IritCurve2Polylines(Crv, Resolution, Optimal);
-
- Poly -> Pnext = PObjPoly -> U.Pl;
- PObjPoly -> U.Pl = Poly;
- }
-
- return PObjPoly;
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Routine to convert a surface to a set of piecewise linear polyline *
- * approximation and convert its control mesh into set of polyline as well. *
- * *
- * PARAMETERS: *
- * PObj: Surfaces to apporximate as a mesh of piecewise linear *
- * isocurves. *
- * Optimal: Do we want an optimal sampling but expensive approach? *
- * *
- * RETURN VALUE: *
- * IPObjectStruct *: A polyline object approximating PObj. *
- *****************************************************************************/
- static IPObjectStruct *ComputeSurfaceIsoLines(IPObjectStruct *PObj,
- int Optimal)
- {
- int Resolution = GetResolution(FALSE);
- IPObjectStruct *PObjPolys;
- CagdSrfStruct *Srf;
-
- if (!IP_IS_SRF_OBJ(PObj))
- IritFatalError("Surface was expected.");
-
- if (Resolution < MIN_FREE_FORM_RES)
- Resolution = MIN_FREE_FORM_RES;
-
- PObjPolys = GenPOLYObject(NULL);
- PObjPolys -> Attrs = AttrCopyAttributes(PObj -> Attrs);
- IP_SET_POLYLINE_OBJ(PObjPolys);
- for (Srf = PObj -> U.Srfs; Srf != NULL; Srf = Srf -> Pnext) {
- int NumOfIso[2];
- IPPolygonStruct *Polys, *PolyTmp;
-
- NumOfIso[0] = NumOfIso[1] = -Resolution;
- Polys = IritSurface2Polylines(Srf, NumOfIso, Resolution, Optimal);
-
- for (PolyTmp = Polys;
- PolyTmp -> Pnext != NULL;
- PolyTmp = PolyTmp -> Pnext);
- PolyTmp -> Pnext = PObjPolys -> U.Pl;
- PObjPolys -> U.Pl = Polys;
- }
-
- return PObjPolys;
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Routine to convert a trimmed surface to a set of piecewise linear polyline *
- * approximation and convert its control mesh into set of polyline as well. *
- * *
- * PARAMETERS: *
- * PObj: Trimmed surfaces to apporximate as a mesh of piecewise *
- * linear isocurves. *
- * Optimal: Do we want an optimal sampling but expensive approach? *
- * *
- * RETURN VALUE: *
- * IPObjectStruct *: A polyline object approximating PObj. *
- *****************************************************************************/
- static IPObjectStruct *ComputeTrimSrfIsoLines(IPObjectStruct *PObj,
- int Optimal)
- {
- int Resolution = GetResolution(FALSE);
- IPObjectStruct *PObjPolys;
- TrimSrfStruct *TrimSrf;
-
- if (!IP_IS_TRIMSRF_OBJ(PObj))
- IritFatalError("Trimmed surface was expected.");
-
- if (Resolution < MIN_FREE_FORM_RES)
- Resolution = MIN_FREE_FORM_RES;
-
- PObjPolys = GenPOLYObject(NULL);
- PObjPolys -> Attrs = AttrCopyAttributes(PObj -> Attrs);
- IP_SET_POLYLINE_OBJ(PObjPolys);
- for (TrimSrf = PObj -> U.TrimSrfs;
- TrimSrf != NULL;
- TrimSrf = TrimSrf -> Pnext) {
- int NumOfIso[2];
- IPPolygonStruct *Polys, *PolyTmp;
-
- NumOfIso[0] = NumOfIso[1] = -Resolution;
- Polys = IritTrimSrf2Polylines(TrimSrf, NumOfIso, Resolution, Optimal,
- TRUE, TRUE);
-
- for (PolyTmp = Polys;
- PolyTmp -> Pnext != NULL;
- PolyTmp = PolyTmp -> Pnext);
- PolyTmp -> Pnext = PObjPolys -> U.Pl;
- PObjPolys -> U.Pl = Polys;
- }
-
- return PObjPolys;
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Routine to convert a trimmed surface to a set of piecewise linear polyline *
- * approximation and convert its control mesh into set of polyline as well. *
- * *
- * PARAMETERS: *
- * PObj: Trimmed surfaces to apporximate as a mesh of piecewise *
- * linear isocurves. *
- * Optimal: Do we want an optimal sampling but expensive approach? *
- * *
- * RETURN VALUE: *
- * IPObjectStruct *: A polyline object approximating PObj. *
- *****************************************************************************/
- static IPObjectStruct *ComputeTrivarIsoLines(IPObjectStruct *PObj,
- int Optimal)
- {
- int Resolution = GetResolution(FALSE);
- IPObjectStruct *PObjPolys;
- TrivTVStruct *Trivar;
-
- if (!IP_IS_TRIVAR_OBJ(PObj))
- IritFatalError("Trivariate function was expected.");
-
- if (Resolution < MIN_FREE_FORM_RES)
- Resolution = MIN_FREE_FORM_RES;
-
- PObjPolys = GenPOLYObject(NULL);
- PObjPolys -> Attrs = AttrCopyAttributes(PObj -> Attrs);
- IP_SET_POLYLINE_OBJ(PObjPolys);
- for (Trivar = PObj -> U.Trivars;
- Trivar != NULL;
- Trivar = Trivar -> Pnext) {
- int NumOfIso[3],
- Res = MAX(Resolution / 2, 2);
- IPPolygonStruct *Polys, *PolyTmp;
-
- NumOfIso[0] = NumOfIso[1] = NumOfIso[2] = -Res;
- Polys = IritTrivar2Polylines(Trivar, NumOfIso, Resolution, Optimal);
-
- for (PolyTmp = Polys;
- PolyTmp -> Pnext != NULL;
- PolyTmp = PolyTmp -> Pnext);
- PolyTmp -> Pnext = PObjPolys -> U.Pl;
- PObjPolys -> U.Pl = Polys;
- }
-
- return PObjPolys;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to convert a surface to a set of polygons approximating it. M
- * Result is saved as an attribute on the surfaces. M
- * If however approximation alread exists, no computation is performed. M
- * *
- * PARAMETERS: M
- * PObj: Surfaces to approximate using polygons. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * ComputeSurfacePolygons M
- *****************************************************************************/
- void ComputeSurfacePolygons(IPObjectStruct *PObj)
- {
- int Resolution = GetResolution(FALSE),
- FourPerFlat = GetFourPerFlat(),
- PolyApproxOpt = GetPolyApproxOptimal(),
- PolyApproxUV = GetPolyApproxUV();
- RealType
- RelResolution = AttrGetObjectRealAttrib(PObj, "resolution"),
- Tolerance = GetPolyApproxTol();
- IPPolygonStruct *Polys;
- IPObjectStruct *PObjPoly;
-
- if (AttrGetObjectObjAttrib(PObj, "_polygons") != NULL)
- return;
-
- if (Resolution < MIN_FREE_FORM_RES)
- Resolution = MIN_FREE_FORM_RES;
- if (RelResolution < IP_ATTR_BAD_REAL)
- Resolution = REAL_TO_INT(Resolution * RelResolution);
-
- #ifndef __MSDOS__
- /* Make the resolution more reasonable (very slow on MSDOS). */
- Resolution *= 2;
- #endif /* __MSDOS__ */
-
- if (AttrGetObjectStrAttrib(PObj, "twoperflat") != NULL)
- FourPerFlat = FALSE;
- if (AttrGetObjectStrAttrib(PObj, "fourperflat") != NULL)
- FourPerFlat = TRUE;
-
- Polys = IritSurface2Polygons(PObj -> U.Srfs, FourPerFlat,
- PolyApproxOpt ? Tolerance : Resolution,
- PolyApproxUV, PolyApproxOpt);
- PObjPoly = GenPolyObject("", Polys, NULL);
- PObjPoly -> Attrs = AttrCopyAttributes(PObj -> Attrs);
- AttrSetObjectObjAttrib(PObj, "_polygons", PObjPoly, FALSE);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to convert a surface/list of surfaces into set of polygons. M
- * *
- * PARAMETERS: M
- * Obj: A geometry to convert and approximate using polygons. M
- * Normals: Do we want normals as well (at vertices)? M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A polygonal object approximating Obj. M
- * *
- * KEYWORDS: M
- * Geometry2Polygons M
- *****************************************************************************/
- IPObjectStruct *Geometry2Polygons(IPObjectStruct *Obj, RealType *Normals)
- {
- IPObjectStruct *PObj;
-
- if (IP_IS_SRF_OBJ(Obj)) {
- if (AttrGetObjectObjAttrib(Obj, "_polygons") != NULL)
- AttrFreeOneAttribute(&Obj -> Attrs, "_polygons");
- ComputeSurfacePolygons(Obj);
- PObj = CopyObject(NULL, AttrGetObjectObjAttrib(Obj, "_polygons"),
- FALSE);
- AttrSetObjectColor(PObj, GlblPrimColor); /* Set its default color. */
-
- if (!REAL_PTR_TO_INT(Normals)) {
- IPPolygonStruct *Pl;
-
- for (Pl = PObj -> U.Pl; Pl != NULL; Pl = Pl -> Pnext) {
- IPVertexStruct
- *V = Pl -> PVertex;
-
- do {
- IP_RST_NORMAL_VRTX(V);
-
- V = V -> Pnext;
- }
- while (V != NULL && V != Pl -> PVertex);
- }
- }
-
- return PObj;
- }
- else if (IP_IS_OLST_OBJ(Obj))
- {
- int i = 0;
- IPPolygonStruct *P;
- IPObjectStruct
- *PObjAll = NULL;
-
- while ((PObj = ListObjectGet(Obj, i++)) != NULL) {
- PObj = Geometry2Polygons(PObj, Normals);
-
- if (PObjAll) {
- if (PObj -> U.Pl) {
- for (P = PObj -> U.Pl;
- P -> Pnext != NULL;
- P = P -> Pnext);
- P -> Pnext = PObjAll -> U.Pl;
- PObjAll -> U.Pl = PObj -> U.Pl;
- PObj -> U.Pl = NULL;
- }
- IPFreeObject(PObj);
- }
- else {
- PObjAll = PObj;
- }
- }
-
- return PObjAll;
- }
- else {
- WndwInputWindowPutStr("Unconvertable to polygons object ignored");
- return NULL;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to convert a surface/curve/list of these into set of polylines. M
- * *
- * PARAMETERS: M
- * Obj: A geometry to convert and approximate using polygons. M
- * Optimal: Do we want an optimal sampling but expensive approach? M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A polyline object approximating Obj. M
- * *
- * KEYWORDS: M
- * Geometry2Polylines M
- *****************************************************************************/
- IPObjectStruct *Geometry2Polylines(IPObjectStruct *Obj, RealType *Optimal)
- {
- IPObjectStruct *PObj;
- IPPolygonStruct *P;
-
- if (IP_IS_CRV_OBJ(Obj)) {
- return ComputeCurveIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
- }
- else if (IP_IS_SRF_OBJ(Obj)) {
- return ComputeSurfaceIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
- }
- else if (IP_IS_TRIMSRF_OBJ(Obj)) {
- return ComputeTrimSrfIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
- }
- else if (IP_IS_TRIVAR_OBJ(Obj)) {
- return ComputeTrivarIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
- }
- else if (IP_IS_OLST_OBJ(Obj))
- {
- int i = 0;
- IPObjectStruct
- *PObjAll = NULL;
-
- while ((PObj = ListObjectGet(Obj, i++)) != NULL) {
- PObj = Geometry2Polylines(PObj, Optimal);
-
- if (PObjAll) {
- if (PObj -> U.Pl) {
- for (P = PObj -> U.Pl;
- P -> Pnext != NULL;
- P = P -> Pnext);
- P -> Pnext = PObjAll -> U.Pl;
- PObjAll -> U.Pl = PObj -> U.Pl;
- PObj -> U.Pl = NULL;
- }
- IPFreeObject(PObj);
- }
- else {
- PObjAll = PObj;
- }
- }
-
- return PObjAll;
- }
- else {
- return NULL;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to return extremum value of control mesh/polygon. M
- * *
- * PARAMETERS: M
- * Obj: Object to bound itsextremum possible values. M
- * Min: TRUE for minimum, FALSE for maximum. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A control points with extremum values. Rational are M
- * Correctly porjected back to Euclidean space. M
- * *
- * KEYWORDS: M
- * ExtremumControlPointVals M
- *****************************************************************************/
- IPObjectStruct *ExtremumControlPointVals(IPObjectStruct *Obj, CagdRType *Min)
- {
- CagdBType
- FindMin = REAL_PTR_TO_INT(Min);
- CagdRType *Extremum,
- **Points = NULL;
- int Len = 0;
- CagdPointType
- PType = CAGD_PT_E1_TYPE;
-
- if (IP_IS_SRF_OBJ(Obj)) {
- Points = Obj -> U.Srfs -> Points;
- Len = Obj -> U.Srfs -> ULength * Obj -> U.Srfs -> VLength;
- PType = Obj -> U.Srfs -> PType;
- }
- else if (IP_IS_CRV_OBJ(Obj)) {
- Points = Obj -> U.Crvs -> Points;
- Len = Obj -> U.Crvs -> Length;
- PType = Obj -> U.Crvs -> PType;
- }
- else {
- IritPrsrFatalError("Extremum allowed on curves/surfaces only");
- return NULL;
- }
-
- Extremum = SymbExtremumCntPtVals(Points, Len, FindMin);
-
- return GenCTLPTObject(PType, Extremum, NULL);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Creates an exact rational quadratic circle parallel to the XY plane. M
- * *
- * PARAMETERS: M
- * Position: Center of circle. M
- * Radius: Radius of circle. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A rational quadratic Bspline curve object M
- * representing a circle. M
- * *
- * KEYWORDS: M
- * GenCircleCurveObject M
- *****************************************************************************/
- IPObjectStruct *GenCircleCurveObject(VectorType Position, RealType *Radius)
- {
- int i;
- CagdPtStruct Pos;
- CagdCrvStruct *CircCrv;
- IPObjectStruct *CrvObj;
-
- for (i = 0; i < 3; i++)
- Pos.Pt[i] = Position[i];
- CircCrv = BspCrvCreateCircle(&Pos, *Radius);
-
- if (CircCrv == NULL)
- return NULL;
-
- CrvObj = GenCRVObject(CircCrv);
-
- return CrvObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Creates an approximated cubic polynomial circle parallel to the XY plane. M
- * *
- * PARAMETERS: M
- * Position: Center of circle. M
- * Radius: Radius of circle. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A cubic polynomial Bspline curve object M
- * representing a circle. M
- * *
- * KEYWORDS: M
- * GenPCircleCurveObject M
- *****************************************************************************/
- IPObjectStruct *GenPCircleCurveObject(VectorType Position, RealType *Radius)
- {
- int i;
- CagdPtStruct Pos;
- CagdCrvStruct *CircCrv;
- IPObjectStruct *CrvObj;
-
- for (i = 0; i < 3; i++)
- Pos.Pt[i] = Position[i];
- CircCrv = BspCrvCreatePCircle(&Pos, *Radius);
-
- if (CircCrv == NULL)
- return NULL;
-
- CrvObj = GenCRVObject(CircCrv);
-
- return CrvObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Creates an arbitrary arc specified by Two end points and Center. Arc must M
- * be less than 180 degree. M
- * *
- * PARAMETERS: M
- * Start: Location of arc. M
- * Center: Location of arc. M
- * End: Location of arc. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A curve representing the requested arc. M
- * *
- * KEYWORDS: M
- * GenArcCurveObject M
- *****************************************************************************/
- IPObjectStruct *GenArcCurveObject(VectorType Start,
- VectorType Center,
- VectorType End)
- {
- int i;
- CagdPtStruct StartPt, CenterPt, EndPt;
- CagdCrvStruct *ArcCrv;
- IPObjectStruct *CrvObj;
-
- for (i = 0; i < 3; i++) {
- StartPt.Pt[i] = Start[i];
- CenterPt.Pt[i] = Center[i];
- EndPt.Pt[i] = End[i];
- }
- ArcCrv = BzrCrvCreateArc(&StartPt, &CenterPt, &EndPt);
-
- if (ArcCrv == NULL)
- return NULL;
-
- CrvObj = GenCRVObject(ArcCrv);
-
- return CrvObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Constructs a ruled surface out of the two provided curves. M
- * *
- * PARAMETERS: M
- * Crv1, Crv2: Two curves to rule a surface between. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A ruled surface object. M
- * *
- * KEYWORDS: M
- * GenRuledSrfObject M
- *****************************************************************************/
- IPObjectStruct *GenRuledSrfObject(IPObjectStruct *Crv1, IPObjectStruct *Crv2)
- {
- IPObjectStruct *SrfObj;
- CagdSrfStruct
- *RuledSrf = CagdRuledSrf(Crv1 -> U.Crvs, Crv2 -> U.Crvs, 2, 2);
-
- if (RuledSrf == NULL)
- return NULL;
-
- SrfObj = GenSRFObject(RuledSrf);
-
- return SrfObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Construct a boolean sum surface out of a single boundary curve. M
- * *
- * PARAMETERS: M
- * BndryCrv: A curve to fill its interior with a surface. Better be close. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A filling surface object. M
- * *
- * KEYWORDS: M
- * GenBoolOneSrfObject M
- *****************************************************************************/
- IPObjectStruct *GenBoolOneSrfObject(IPObjectStruct *BndryCrv)
- {
- IPObjectStruct *SrfObj;
- CagdSrfStruct
- *BoolSumSrf = CagdOneBoolSumSrf(BndryCrv -> U.Crvs);
-
- if (BoolSumSrf == NULL)
- return NULL;
-
- SrfObj = GenSRFObject(BoolSumSrf);
-
- return SrfObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Construct a boolean sum surface out of the four provided curves. M
- * *
- * PARAMETERS: M
- * Crv1, Crv2, Crv3, Crv4: Four curves to construct a Boolean sum between. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: The Boolean sum surface. M
- * *
- * KEYWORDS: M
- * GenBoolSumSrfObject M
- *****************************************************************************/
- IPObjectStruct *GenBoolSumSrfObject(IPObjectStruct *Crv1,
- IPObjectStruct *Crv2,
- IPObjectStruct *Crv3,
- IPObjectStruct *Crv4)
- {
- IPObjectStruct *SrfObj;
- CagdSrfStruct
- *BoolSumSrf = CagdBoolSumSrf(Crv1 -> U.Crvs,
- Crv2 -> U.Crvs,
- Crv3 -> U.Crvs,
- Crv4 -> U.Crvs);
-
- if (BoolSumSrf == NULL)
- return NULL;
-
- SrfObj = GenSRFObject(BoolSumSrf);
-
- return SrfObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Construct a surface out of the provided curve list. M
- * *
- * PARAMETERS: M
- * CrvList: A list of curves to approximate a surface through. M
- * OtherOrder: Other order of surface. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A surface approximately traversing through the given M
- * curves. M
- * *
- * KEYWORDS: M
- * GenSrfFromCrvsObject M
- *****************************************************************************/
- IPObjectStruct *GenSrfFromCrvsObject(IPObjectStruct *CrvList,
- RealType *OtherOrder)
- {
- int i,
- NumCrvs = 0;
- IPObjectStruct *SrfObj, *CrvObj, *PrevCrvObj, *HeadCrvObj;
- CagdSrfStruct *Srf;
- CagdCrvStruct *Crv,
- *Crvs = NULL;
-
-
- if (!IP_IS_OLST_OBJ(CrvList))
- IritFatalError("SURFACE: Not object list object!");
-
- while ((CrvObj = ListObjectGet(CrvList, NumCrvs)) != NULL) {
- if (!IP_IS_CRV_OBJ(CrvObj)) {
- IritPrsrFatalError("SURFACE: List contains non curve object(s).");
- return NULL;
- }
- if (CrvObj -> U.Crvs -> Pnext != NULL) {
- IritPrsrFatalError("SURFACE: nested curve lists are disallowed.");
- return NULL;
- }
- NumCrvs++;
- }
-
- /* Chain all curves into a single list and invoke the srf constructor: */
- HeadCrvObj = PrevCrvObj = ListObjectGet(CrvList, 0);
- for (i = 0; i < NumCrvs; i++) {
- CrvObj = ListObjectGet(CrvList, i);
- Crv = CagdCrvCopy(CrvObj -> U.Crvs);
- LIST_PUSH(Crv, Crvs);
- }
-
- Crvs = CagdListReverse(Crvs);
- Srf = CagdSrfFromCrvs(Crvs, REAL_PTR_TO_INT(OtherOrder));
- CagdCrvFreeList(Crvs);
-
- if (Srf == NULL)
- return NULL;
-
- SrfObj = GenSRFObject(Srf);
-
- return SrfObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Constructs a Sweep surface out of the CrossSection curve, Axis curve and M
- * optional Scaling curve and Scaler which scales the CrossSection. M
- * *
- * PARAMETERS: M
- * CrossSection: Cross section of sweep. M
- * Axis: Axis curve of sweep. M
- * Frame: Orientation specification. Either an orientation curve M
- * Or a vector specification. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A sweep surface. M
- * *
- * KEYWORDS: M
- * GenSweepSrfObject M
- *****************************************************************************/
- IPObjectStruct *GenSweepSrfObject(IPObjectStruct *CrossSection,
- IPObjectStruct *Axis,
- IPObjectStruct *Frame)
- {
- IPObjectStruct *SrfObj;
- int FrameIsCrv = IP_IS_CRV_OBJ(Frame),
- HasFrame = FrameIsCrv || IP_IS_VEC_OBJ(Frame);
- CagdSrfStruct *SweepSrf;
-
- SweepSrf = CagdSweepSrf(CrossSection -> U.Crvs, Axis -> U.Crvs, NULL, 1.0,
- HasFrame ? (FrameIsCrv
- ? (VoidPtr) Frame -> U.Crvs
- : (VoidPtr) Frame -> U.Vec)
- : NULL,
- FrameIsCrv);
-
- if (SweepSrf == NULL)
- return NULL;
-
- SrfObj = GenSRFObject(SweepSrf);
-
- return SrfObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Constructs a Sweep surface out of the CrossSection curve, Axis curve and M
- * optional Scaling curve and Scaler which scales the CrossSection. M
- * *
- * PARAMETERS: M
- * CrossSection: Cross section of sweep. M
- * Axis: Axis curve of sweep. M
- * Scale: Either a numeric constant scale or a scaling scalar curve.M
- * Frame: Orientation specification. Either an orientation curve M
- * Or a vector specification. M
- * RRefine: Refinement control. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A sweep surface. M
- * *
- * KEYWORDS: M
- * GenSweepScaleSrfObject M
- *****************************************************************************/
- IPObjectStruct *GenSweepScaleSrfObject(IPObjectStruct *CrossSection,
- IPObjectStruct *Axis,
- IPObjectStruct *Scale,
- IPObjectStruct *Frame,
- RealType *RRefine)
- {
- IPObjectStruct *SrfObj;
- int FrameIsCrv = IP_IS_CRV_OBJ(Frame),
- HasFrame = FrameIsCrv || IP_IS_VEC_OBJ(Frame),
- Refine = REAL_PTR_TO_INT(RRefine);
- CagdCrvStruct
- *AxisCrv = Axis -> U.Crvs;
- CagdSrfStruct *SweepSrf;
-
- if (IP_IS_CRV_OBJ(Scale)) {
- CagdCrvStruct
- *TCrv = CagdSweepAxisRefine(AxisCrv, Scale -> U.Crvs, Refine);
-
- AxisCrv = TCrv;
- }
-
- SweepSrf = CagdSweepSrf(CrossSection -> U.Crvs, AxisCrv,
- IP_IS_CRV_OBJ(Scale) ? Scale -> U.Crvs : NULL,
- IP_IS_NUM_OBJ(Scale) ? Scale -> U.R : 1.0,
- HasFrame ? (FrameIsCrv
- ? (VoidPtr) Frame -> U.Crvs
- : (VoidPtr) Frame -> U.Vec)
- : NULL,
- FrameIsCrv);
-
- if (AxisCrv != Axis -> U.Crvs)
- CagdCrvFree(AxisCrv);
-
- if (SweepSrf == NULL)
- return NULL;
-
- SrfObj = GenSRFObject(SweepSrf);
-
- return SrfObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Computes an approximation to the offset of a (planar) curve or a surface. M
- * *
- * PARAMETERS: M
- * Obj: Curve to approximate its offset by Offset amount. M
- * Offset: Amount of offset. M
- * Tolerance: Accuracy of offset. M
- * BezInterp: Do we want Bezier interpolation or approximation? M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: An offset approximating to Obj. M
- * *
- * KEYWORDS: M
- * GenOffsetObject M
- *****************************************************************************/
- IPObjectStruct *GenOffsetObject(IPObjectStruct *Obj,
- RealType *Offset,
- RealType *Tolerance,
- RealType *BezInterp)
- {
- if (IP_IS_SRF_OBJ(Obj)) {
- IPObjectStruct *SrfObj;
- CagdSrfStruct
- *OffsetSrf = SymbSrfSubdivOffset(Obj -> U.Srfs, *Offset,
- *Tolerance);
-
- if (OffsetSrf == NULL)
- return NULL;
-
- SrfObj = GenSRFObject(OffsetSrf);
-
- return SrfObj;
- }
- else if (IP_IS_CRV_OBJ(Obj)) {
- IPObjectStruct *CrvObj;
- CagdCrvStruct
- *OffsetCrv = SymbCrvSubdivOffset(Obj -> U.Crvs, *Offset,
- *Tolerance,
- REAL_PTR_TO_INT(BezInterp));
-
- if (OffsetCrv == NULL)
- return NULL;
-
- CrvObj = GenCRVObject(OffsetCrv);
-
- return CrvObj;
- }
- else {
- IritPrsrFatalError("Offset allowed on curves/surfaces only");
- return NULL;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Computes an approximation to the offset of a (planar) curve or a surface. M
- * This offset is computed and approximated to with a given tolerance M
- * Epsilon that is related to the square of the distance between the original M
- * curve and its offset approximation. M
- * If Trim then regions in the curve with curvature that is larger than M
- * offset distance required will be trimmed out. M
- * *
- * PARAMETERS: M
- * Obj: Curve to approximate its offset by Offset amount. M
- * Offset: Amount of offset. M
- * Epsilon: Accuracy of offset. M
- * Trim: Shouldwe deal and trim self intersecting loops? M
- * BezInterp: Do we want Bezier interpolation or approximation? M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: An offset approximating to Obj. M
- * *
- * KEYWORDS: M
- * GenAOffsetObject M
- *****************************************************************************/
- IPObjectStruct *GenAOffsetObject(IPObjectStruct *Obj,
- RealType *Offset,
- RealType *Epsilon,
- RealType *Trim,
- RealType *BezInterp)
- {
- if (IP_IS_SRF_OBJ(Obj)) {
- IritPrsrFatalError("Adaptive offset is not supported for surfaces");
- return NULL;
- }
- else if (IP_IS_CRV_OBJ(Obj)) {
- IPObjectStruct *CrvObj;
- CagdCrvStruct
- *OffsetCrv = APX_EQ(*Trim, 0.0) ?
- SymbCrvAdapOffset(Obj -> U.Crvs, *Offset, *Epsilon,
- NULL, REAL_PTR_TO_INT(BezInterp)) :
- SymbCrvAdapOffsetTrim(Obj -> U.Crvs, *Offset,
- *Epsilon, NULL,
- REAL_PTR_TO_INT(BezInterp));
-
- if (OffsetCrv == NULL)
- return NULL;
- else
- CrvObj = GenCRVObject(OffsetCrv);
-
- return CrvObj;
- }
- else {
- IritPrsrFatalError("Offset allowed on curves/surfaces only");
- return NULL;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Computes an approximation to the offset of a (planar) curve or a surface. M
- * This offset is computed and approximated using a least sqaure fit. M
- * *
- * PARAMETERS: M
- * Obj: Curve to approximate its offset by Offset amount. M
- * Offset: Amount of offset. M
- * NumOfSamples: To sample the offset curve. M
- * NumOfDOF: Number of control points in resulting approximation. M
- * Order: Of resulting approximation. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: An offset approximating to Obj. M
- * *
- * KEYWORDS: M
- * GenLeastSqrOffsetObject M
- *****************************************************************************/
- IPObjectStruct *GenLeastSqrOffsetObject(IPObjectStruct *Obj,
- RealType *Offset,
- RealType *NumOfSamples,
- RealType *NumOfDOF,
- RealType *Order)
- {
- CagdRType Tolerance;
-
- if (IP_IS_CRV_OBJ(Obj)) {
- CagdCrvStruct
- *OffsetCrv = SymbCrvLeastSquarOffset(Obj -> U.Crvs,
- *Offset,
- REAL_PTR_TO_INT(NumOfSamples),
- REAL_PTR_TO_INT(NumOfDOF),
- REAL_PTR_TO_INT(Order),
- &Tolerance);
-
- if (OffsetCrv == NULL)
- return NULL;
- else
- return GenCRVObject(OffsetCrv);
- }
- else {
- IritPrsrFatalError("LOffset allowed on curves only");
- return NULL;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Affine reparametrization, effectively changing the domain of the curve. M
- * *
- * PARAMETERS: M
- * Obj: A curve to change its parametric domain. M
- * TMin, TMax: New domain for Obj. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A curve identical to Crv but with parametric domain M
- * from TMin to TMax. M
- * *
- * KEYWORDS: M
- * CrvReparametrization M
- *****************************************************************************/
- IPObjectStruct *CrvReparametrization(IPObjectStruct *Obj,
- RealType *TMin,
- RealType *TMax)
- {
- IPObjectStruct *CrvObj;
- CagdCrvStruct
- *Crv = CAGD_IS_BEZIER_CRV(Obj -> U.Crvs) ?
- CnvrtBezier2BsplineCrv(Obj -> U.Crvs) :
- CagdCrvCopy(Obj -> U.Crvs);
- int Len = Crv -> Length + Crv -> Order;
- CagdRType
- *KV = Crv -> KnotVector;
-
- /* Translate to 0.0, scale, and translate to new location. */
- BspKnotAffineTrans(KV, Len, -KV[0], 1.0);
- BspKnotAffineTrans(KV, Len, 0.0, (*TMax - *TMin) / (KV[Len - 1] - KV[0]));
- BspKnotAffineTrans(KV, Len, *TMin, 1.0);
-
- CrvObj = GenCRVObject(Crv);
-
- return CrvObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Affine reparametrization, effectively changing the domain of the curve. M
- * *
- * PARAMETERS: M
- * Obj: A surface to change its parametric domain. M
- * RDir: Direction of reparametrization. Either U or V. M
- * TMin, TMax: New domain for Obj. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A surface identical to Srf but with parametric M
- * domain from TMin to TMax in direction RDir. M
- * *
- * KEYWORDS: M
- * SrfReparametrization M
- *****************************************************************************/
- IPObjectStruct *SrfReparametrization(IPObjectStruct *Obj,
- RealType *RDir,
- RealType *TMin,
- RealType *TMax)
- {
- IPObjectStruct *SrfObj;
- CagdSrfDirType
- Dir = REAL_PTR_TO_INT(RDir);
- CagdSrfStruct
- *Srf = CAGD_IS_BEZIER_SRF(Obj -> U.Srfs) ?
- CnvrtBezier2BsplineSrf(Obj -> U.Srfs) :
- CagdSrfCopy(Obj -> U.Srfs);
- int Len = Dir == CAGD_CONST_U_DIR ? Srf -> ULength + Srf -> UOrder
- : Srf -> VLength + Srf -> VOrder;
- CagdRType
- *KV = Dir == CAGD_CONST_U_DIR ? Srf -> UKnotVector : Srf -> VKnotVector;
-
- /* Translate to 0.0, scale, and translate to new location. */
- BspKnotAffineTrans(KV, Len, -KV[0], 1.0);
- BspKnotAffineTrans(KV, Len, 0.0, (*TMax - *TMin) / (KV[Len - 1] - KV[0]));
- BspKnotAffineTrans(KV, Len, *TMin, 1.0);
-
- SrfObj = GenSRFObject(Srf);
-
- return SrfObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Computes curvature properties of the given curve. M
- * *
- * PARAMETERS: M
- * PObj: Curve to evaluate its curvature properties. M
- * Eps: Accuracy of computation. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: Either extremum curvature locations if Eps > 0, or M
- * curvature field square curve if Eps < 0. M
- * *
- * KEYWORDS: M
- * CrvCurvaturePts M
- *****************************************************************************/
- IPObjectStruct *CrvCurvaturePts(IPObjectStruct *PObj, RealType *Eps)
- {
- IPObjectStruct *NewPObj;
-
- if (CAGD_NUM_OF_PT_COORD(PObj -> U.Crvs -> PType) < 2 ||
- CAGD_NUM_OF_PT_COORD(PObj -> U.Crvs -> PType) > 3) {
- IritPrsrFatalError(
- "CCRVTR: Only 2 or 3 dimensional curves are supported.");
- return NULL;
- }
-
- if (*Eps <= 0.0) {
- CagdRType TMin, TMax;
- CagdCrvStruct *CrvtrCrv2D,
- *CrvtrCrv = SymbCrv3DCurvatureSqr(PObj -> U.Crvs);
-
- CagdCrvDomain(PObj -> U.Crvs, &TMin, &TMax);
- CrvtrCrv2D = SymbPrmtSclrCrvTo2D(CrvtrCrv, TMin, TMax);
- CagdCrvFree(CrvtrCrv);
-
- NewPObj = GenCRVObject(CrvtrCrv2D);
- }
- else {
- int i;
- CagdPtStruct *IPtsTmp,
- *IPts = SymbCrv2DExtremCrvtrPts(PObj -> U.Crvs, *Eps);
-
- NewPObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
-
- for (IPtsTmp = IPts, i = 0;
- IPtsTmp != NULL;
- IPtsTmp = IPtsTmp -> Pnext, i++) {
- ListObjectInsert(NewPObj, i, GenNUMValObject(IPtsTmp -> Pt[0]));
- }
-
- CagdPtFreeList(IPts);
-
- ListObjectInsert(NewPObj, i, NULL);
- }
-
- return NewPObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Computes curvature properties of the given surface. M
- * *
- * PARAMETERS: M
- * PObj: Surface to compute curvature properties for. M
- * RPtType: Point type of output. M
- * RDir: Either curvature in U or V or total upper bound. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A curvature bound field for surface PObj. M
- * *
- * KEYWORDS: M
- * SrfCurvatureBounds M
- *****************************************************************************/
- IPObjectStruct *SrfCurvatureBounds(IPObjectStruct *PObj,
- RealType *RPtType,
- RealType *RDir)
- {
- IPObjectStruct *NewPObj;
- CagdSrfStruct *TSrf, *CrvtrSrfBound;
- CagdPointType
- PtType = REAL_PTR_TO_INT(RPtType);
- CagdSrfDirType
- Dir = REAL_PTR_TO_INT(RDir);
-
- if (CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) < 2 ||
- CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) > 3) {
- IritPrsrFatalError(
- "SCRVTR: Only 2 or 3 dimensional curves are supported.");
- return NULL;
- }
-
- switch (Dir) {
- case CAGD_CONST_U_DIR:
- case CAGD_CONST_V_DIR:
- CrvtrSrfBound = SymbSrfIsoDirNormalCurvatureBound(PObj -> U.Srfs,
- Dir);
- break;
- default:
- CrvtrSrfBound = SymbSrfCurvatureUpperBound(PObj -> U.Srfs);
- break;
- }
-
- switch (PtType) {
- case CAGD_PT_P1_TYPE:
- break;
- case CAGD_PT_E1_TYPE:
- case CAGD_PT_E3_TYPE:
- case CAGD_PT_P3_TYPE:
- TSrf = CagdCoerceSrfTo(CrvtrSrfBound, PtType);
- CagdSrfFree(CrvtrSrfBound);
- CrvtrSrfBound = TSrf;
- break;
- default:
- CagdSrfFree(CrvtrSrfBound);
- IritPrsrFatalError("SCRVTR: Wrong point type coercion.");
- return NULL;
- }
-
- NewPObj = GenSRFObject(CrvtrSrfBound);
-
- return NewPObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Computes the evolute curve of the given curve. M
- * *
- * PARAMETERS: M
- * PObj: Curve to compute its evolute curve for. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: An evolute curve of PObj. M
- * *
- * KEYWORDS: M
- * CrvEvolute M
- *****************************************************************************/
- IPObjectStruct *CrvEvolute(IPObjectStruct *PObj)
- {
- IPObjectStruct *NewPObj;
- CagdCrvStruct *EvoluteCrv, *EvoluteCrvAux;
-
- if (CAGD_NUM_OF_PT_COORD(PObj -> U.Crvs -> PType) < 2 ||
- CAGD_NUM_OF_PT_COORD(PObj -> U.Crvs -> PType) > 3) {
- IritPrsrFatalError(
- "CEVOLUTE: Only 2 or 3 dimensional curves are supported.");
- return NULL;
- }
-
- EvoluteCrvAux = SymbCrv3DRadiusNormal(PObj -> U.Crvs);
- EvoluteCrv = SymbCrvAdd(PObj -> U.Crvs, EvoluteCrvAux);
- CagdCrvFree(EvoluteCrvAux);
-
- NewPObj = GenCRVObject(EvoluteCrv);
-
- return NewPObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Merges two surfaces into one in specified Dir and SameEdge flag. M
- * *
- * PARAMETERS: M
- * Srf1, Srf2: Two surfaces to merge. M
- * Dir: Direction of merge. Either U or V. M
- * SameEdge: Do Srf1 and Srf2 share a common edge? M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: A surface result of the merge. M
- * *
- * KEYWORDS: M
- * MergeSrfSrf M
- *****************************************************************************/
- IPObjectStruct *MergeSrfSrf(IPObjectStruct *Srf1,
- IPObjectStruct *Srf2,
- RealType *Dir,
- RealType *SameEdge)
- {
- IPObjectStruct *SrfObj;
- CagdSrfStruct
- *Srf = CagdMergeSrfSrf(Srf1 -> U.Srfs, Srf2 -> U.Srfs,
- REAL_PTR_TO_INT(Dir), REAL_PTR_TO_INT(SameEdge),
- TRUE);
-
- SrfObj = GenSRFObject(Srf);
-
- return SrfObj;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Merge two curves/ctl points into one curve by adding a linear segment M
- * between the first end point to second start point. M
- * *
- * PARAMETERS: M
- * PObj1, PObj2: Either curve or a control point to merge. M
- * *
- * RETURN VALUE: M
- * IPObjectStruct *: Merged curve. M
- * *
- * KEYWORDS: M
- * MergeCurvesAndCtlPoints M
- *****************************************************************************/
- IPObjectStruct *MergeCurvesAndCtlPoints(IPObjectStruct *PObj1,
- IPObjectStruct *PObj2)
- {
- IPObjectStruct *CrvObj;
- CagdCrvStruct
- *Crv = NULL;
- CagdPtStruct Pt1, Pt2;
-
- if (IP_IS_CRV_OBJ(PObj1)) {
- if (IP_IS_CRV_OBJ(PObj2)) {
- Crv = CagdMergeCrvCrv(PObj1 -> U.Crvs, PObj2 -> U.Crvs, TRUE);
- }
- else if (IP_IS_CTLPT_OBJ(PObj2)) {
- CagdRType
- *Coords2 = PObj2 -> U.CtlPt.Coords;
-
- CagdCoerceToE3(Pt2.Pt, &Coords2, -1, PObj2 -> U.CtlPt.PtType);
- Crv = CagdMergeCrvPt(PObj1 -> U.Crvs, &Pt2);
- }
- else
- IritFatalError("Curve/CtlPt was expected.");
- }
- else if (IP_IS_CTLPT_OBJ(PObj1)) {
- CagdRType
- *Coords1 = PObj1 -> U.CtlPt.Coords;
-
- CagdCoerceToE3(Pt1.Pt, &Coords1, -1, PObj1 -> U.CtlPt.PtType);
-
- if (IP_IS_CRV_OBJ(PObj2)) {
- Crv = CagdMergePtCrv(&Pt1, PObj2 -> U.Crvs);
- }
- else if (IP_IS_CTLPT_OBJ(PObj2)) {
- CagdRType
- *Coords2 = PObj2 -> U.CtlPt.Coords;
-
- CagdCoerceToE3(Pt2.Pt, &Coords2, -1, PObj2 -> U.CtlPt.PtType);
- Crv = CagdMergePtPt(&Pt1, &Pt2);
- }
- else
- IritFatalError("Curve/CtlPt was expected.");
- }
- else
- IritFatalError("Curve/CtlPt was expected.");
-
- if (Crv == NULL)
- return NULL;
-
- CrvObj = GenCRVObject(Crv);
-
- return CrvObj;
- }
-